﻿#include <iostream>
#include <string>
#include "SignalSlot.h"

#include <thread>
#include <chrono>
#include "BlockingQueue.h"

#include <stdio.h>


using namespace mufun;

// 普通函数
void printMessage(const std::string& msg) {
    std::cout << "Slot 1: " << msg << std::endl;
}

// 带状态的槽
class MessagePrinter {
public:
    void print(const std::string& msg) {
        std::cout << "Slot 2: " << msg << " (from MessagePrinter)" << std::endl;
    }

    void print2(int num) {
        std::cout << "get a num" << num << " (from MessagePrinter)" << std::endl;
    }
};


void sendnum(BlockingQueue<int>& queue, int num)
{
    queue.enqueue(num);
}

void printnum(const int& num)
{
    printf("this is a num %d\n", num);
}

void printnum2(int num)
{
    printf("this is a num %d\n", num);
    std::cout << " completed by thread " << std::this_thread::get_id() << std::endl;
}

int main() {

    std::cout << " main thread " << std::this_thread::get_id() << std::endl;

    Signal<void(const std::string&)> signal;

    // 普通函数作为槽
    Conn conn1 = signal.connect(printMessage);

    // 成员函数作为槽
    MessagePrinter printer;
    auto conn2 = signal.connect([&printer](const std::string& msg) {
        printer.print(msg);
    });

    // 触发信号
    //signal("Hello, SignalSlot!");
    signal.call("qwqwqwqwqwqw");

    // 手动断开连接
    signal.disconnect(conn1);

    // 再次触发信号
    signal("Hello again!");




    //测试通过队列将数据传给独立的线程
    {
        //简单测试
        Signal<void( int)> signal;

        auto conn2 = signal.connect([]( int num){
            printf("this is a num %d\n", num);
            std::cout << " completed by thread " << std::this_thread::get_id() << std::endl;

            num = 454545;
        }, true);

        // printf("main sleet\n");
        // std::this_thread::sleep_for(std::chrono::milliseconds(300));
        // printf("main aweak\n");

        int num = 312;
        signal.call(std::move(num));

        printf("main sleet\n");
        std::this_thread::sleep_for(std::chrono::milliseconds(300));
        printf("main aweak\n");

        printf("check num is %d\n", num);



        //队列将数据传给独立的线程
        BlockingQueue<int> numlist;
        std::thread mythread([&](){

            int num = numlist.dequeue();

            printf("get a num %d\n", num);
            std::cout << " completed by thread " << std::this_thread::get_id() << std::endl;
        });

        Signal<void(BlockingQueue<int>&, int)> signal2;
        auto conn3 = signal2.connect(sendnum);
        signal2.call(numlist, std::move(num));

        mythread.join();

std::shared_ptr<int> tie(new int);
MessagePrinter ppp;

        //auto pb = std::bind(&MessagePrinter::print2, &ppp, std::placeholders::_1);

        //Conn mys = RegisterExtension(SignalSign::ReadFile, ReadFileFuncType, printnum2);
        //Conn mys = RegisterExtension(SignalSign::ReadFile, ReadFileFuncType, std::bind(&MessagePrinter::print2, &ppp, std::placeholders::_1));
        Conn mys = RegisterExtension(ReadFile, std::bind(&MessagePrinter::print2, &ppp, std::placeholders::_1));
        //Conn mys = RegisterExtensionTie(SignalSign::ReadFile, ReadFileFuncType, printnum2, tie);
        tie = nullptr;

        // UnRegisterExtension(mys);

        //  RegisterExtensionAsync(SignalSign::ReadFile, ReadFileFuncType, printnum2);
        CallExtension(ReadFile, 202514);
    }
    return 0;
}
